package com.shundr.auth.frame.http;

import java.io.File;
import java.util.Locale;
import java.util.Map;

import org.apache.http.Header;
import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.telephony.TelephonyManager;

import com.google.gson.GsonBuilder;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.SimpleMultipartEntity;
import com.shundr.auth.common.view.SharedPrefUtil;
import com.shundr.auth.frame.constant.LCommands;
import com.shundr.auth.frame.constant.LConstants;
import com.shundr.auth.frame.constant.LContext;
import com.shundr.auth.frame.http.HttpRequest.RequestListener;
import com.shundr.auth.frame.util.LLogger;

/**
 * 网络请求池
 * 
 * @author larry
 * 
 */
public class HttpExecutor {

	private static final String COMMAND = "CMDId";
	private static final String JSON = "JSon";
	private static final String TOKEN = "Token";
	private static final String MD5 = "MD5";
	private static final String MD5_VALUE = "";// MD5加密值，目前没有用到，先默认空字符串

	private static AsyncHttpClient mClient = new AsyncHttpClient();
	
	private static Context mContext;

	// private static SyncHttpClient mClient = new SyncHttpClient();

	/**
	 * 初始化HttpExecutor,开启应用时初始化
	 */
	public static void init(Context context) {
		if (mClient == null) {
			mClient = new AsyncHttpClient();
			mClient.setTimeout(20000);
		}
		
		mContext = context;
	}

	/**
	 * 　　* 定义一个异步网络客户端 默认超时未20秒 当超过，默认重连次数为5次 默认最大连接数为10个 　　
	 */
	static {
		mClient.setTimeout(20000);
	}

	/**
	 * post 请求
	 * 
	 * @param url
	 *            API 地址
	 * @param params
	 *            请求的参数
	 * @param handler
	 *            数据加载句柄对象
	 */
	public static void post(String url, RequestParams params,
			AsyncHttpResponseHandler handler) {
		mClient.post(url, params, handler);
	}

	public static void get(String url, RequestParams params,
			AsyncHttpResponseHandler handler) {
		mClient.get(url, params, handler);
	}

	/**
	 * 
	 * requestByPost(这里用一句话描述这个方法的作用) post请求方式 (这里描述这个方法适用条件 – 可选)
	 * 
	 * @param command
	 * @param map
	 * @param requestListener
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	public static void requestByPost(final String command,
			Map<String, Object> map, final RequestListener requestListener) {
		map.put("accessToken", LContext.getACCESS_TOKEN());
		map.put("staffAccessToken", LContext.getSTAFF_TOKEN());
		
		putBaseMap(map);
		final String requestJson = new GsonBuilder().disableHtmlEscaping()
				.create().toJson(map);
		try {
			String url = LCommands.BASE_URL + command;
			RequestParams params = new RequestParams();
			for (String key : map.keySet()) {
				params.put(key, map.get(key));
			}
			// params.put("accessToken", LContext.ACCESS_TOKEN);
			final long start = System.currentTimeMillis();
			mClient.post(url, params, new JsonHttpResponseHandler() {

				@Override
				public void onStart() {
					super.onStart();
					LLogger.e("本次请求基本参数： " + requestJson + " \n " + "接口： "
							+ command);
				}

				@Override
				public void onFinish() {
					super.onFinish();
					LLogger.e("本次请求[" + command + "]耗时:"
							+ (System.currentTimeMillis() - start));
				}

				@Override
				public void onSuccess(int statusCode, Header[] headers,
						JSONObject response) {
					// LLogger.e("onSuccess" + response.toString());
					requestListener.requestCompleted(response.toString());
				}

				@Override
				public void onFailure(int statusCode, Header[] headers,
						String responseString, Throwable throwable) {
					LLogger.e("onFailure" + responseString);
					throwable.printStackTrace();
					requestListener.requestCompleted(null);
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * requestByGet(这里用一句话描述这个方法的作用) 通过get方式请求网络 (这里描述这个方法适用条件 – 可选)
	 * 
	 * @param command
	 * @param map
	 * @param requestListener
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	public static void requestByGet(final String command,
			Map<String, Object> map, final RequestListener requestListener) {
		map.put("accessToken", LContext.getACCESS_TOKEN());
		map.put("staffAccessToken", LContext.getSTAFF_TOKEN());
		putBaseMap(map);
		final String requestJson = new GsonBuilder().disableHtmlEscaping()
				.create().toJson(map);
		try {
			String url = LCommands.BASE_URL + command;
			RequestParams params = new RequestParams();
			for (String key : map.keySet()) {
				params.put(key, map.get(key));
			}
			// params.put("accessToken", LContext.ACCESS_TOKEN);
			final long start = System.currentTimeMillis();
			mClient.get(url, params, new JsonHttpResponseHandler() {

				@Override
				public void onStart() {
					super.onStart();
					LLogger.e("本次请求基本参数： " + requestJson + " \n" + "接口： "
							+ command);
				}

				@Override
				public void onFinish() {
					super.onFinish();
					LLogger.e("本次请求[" + command + "]耗时:"
							+ (System.currentTimeMillis() - start));
				}

				@Override
				public void onSuccess(int statusCode, Header[] headers,
						JSONObject response) {
					// LLogger.e("onSuccess" + response.toString());
					requestListener.requestCompleted(response.toString());
				}

				@Override
				public void onFailure(int statusCode, Header[] headers,
						String responseString, Throwable throwable) {
					LLogger.e("onFailure" + responseString);
					requestListener.requestCompleted(null);
				}

				@Override
				public void onFailure(int statusCode, Header[] headers,
						Throwable throwable, JSONArray errorResponse) {
					super.onFailure(statusCode, headers, throwable,
							errorResponse);
					LLogger.e("onFailure---" + statusCode);
					requestListener.requestCompleted(null);
				}

				@Override
				public void onFailure(int statusCode, Header[] headers,
						Throwable throwable, JSONObject errorResponse) {
					super.onFailure(statusCode, headers, throwable,
							errorResponse);
					LLogger.e("onFailure ： " + "网络异常");
					requestListener.requestCompleted(null);
				}

			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 上传图片 uploadImage(这里用一句话描述这个方法的作用) (这里描述这个方法适用条件 – 可选)
	 * 
	 * @param command
	 * @param map
	 * @param requestListener
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	public static void uploadImage(Context context, final String command,
			Map<String, Object> map, final RequestListener requestListener) {
		map.put("accessToken", LContext.getACCESS_TOKEN());
		map.put("staffAccessToken", LContext.getSTAFF_TOKEN());
		final String requestJson = new GsonBuilder().disableHtmlEscaping()
				.create().toJson(map);
		putBaseMap(map);
		try {
			String url = LCommands.BASE_URL + command;
			final long start = System.currentTimeMillis();
			SimpleMultipartEntity entity = new SimpleMultipartEntity(
					new JsonHttpResponseHandler());
			entity.addPart("accessToken", LContext.getACCESS_TOKEN());
			entity.addPart("id", "id1");
			entity.addPart("type", map.get("type").toString());
			entity.addPart("file", (File) map.get("file"));
			mClient.post(context, url, entity, "multipart/form-data",
					new JsonHttpResponseHandler() {

						@Override
						public void onStart() {
							super.onStart();
							LLogger.e("本次请求基本参数： " + requestJson + " \n"
									+ "接口： " + command);
						}

						@Override
						public void onFinish() {
							super.onFinish();
							LLogger.e("本次请求[" + command + "]耗时:"
									+ (System.currentTimeMillis() - start));
						}

						@Override
						public void onSuccess(int statusCode, Header[] headers,
								JSONObject response) {
							// LLogger.e("onSuccess" + response.toString());
							requestListener.requestCompleted(response
									.toString());
						}

						@Override
						public void onFailure(int statusCode, Header[] headers,
								String responseString, Throwable throwable) {
							LLogger.e("onFailure" + responseString);
							requestListener.requestCompleted(null);
						}

						@Override
						public void onFailure(int statusCode, Header[] headers,
								Throwable throwable, JSONArray errorResponse) {
							super.onFailure(statusCode, headers, throwable,
									errorResponse);
							LLogger.e("onFailure---" + statusCode);
							requestListener.requestCompleted(null);
						}

						@Override
						public void onFailure(int statusCode, Header[] headers,
								Throwable throwable, JSONObject errorResponse) {
							super.onFailure(statusCode, headers, throwable,
									errorResponse);
							LLogger.e("onFailure ： " + "网络异常");
							requestListener.requestCompleted(null);
						}

					});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 封装必传信息
	 * putBaseMap(这里用一句话描述这个方法的作用)
	 * (这里描述这个方法适用条件 – 可选)
	 * @param map
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	private static void putBaseMap(Map<String, Object> map){
		// 手机sdk版本
		int sdk = Build.VERSION.SDK_INT;
		String release = android.os.Build.VERSION.RELEASE;
		// 获取手机品牌

		String brand = Build.BRAND;
		String model = android.os.Build.MODEL;
		// 获取手机语言
		String locale = Locale.getDefault().getLanguage();
		// version code
		int versionCode = 0;
		try {
			versionCode = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode;
		} catch (NameNotFoundException e1) {
			e1.printStackTrace();
		}
		// imei imsi
		TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
		// 89860113817058951155
		String imei = tm.getSimSerialNumber();
		// 460011886607072
		String imsi = tm.getSubscriberId();
		map.put("sdk", sdk);
		map.put("release", release);
		map.put("brand", brand);
		map.put("model", model);
		map.put("locale", locale);
		map.put("versionCode", versionCode);
		map.put("imei", imei);
		map.put("imsi", imsi);
	}

}
